home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mm / mm-0.90 / keywords.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-18  |  10.0 KB  |  509 lines

  1. /*
  2.  * Copyright (c) 1986, 1990 by The Trustees of Columbia University in
  3.  * the City of New York.  Permission is granted to any individual or
  4.  * institution to use, copy, or redistribute this software so long as it
  5.  * is not sold for profit, provided this copyright notice is retained.
  6.  */
  7.  
  8. #ifndef lint
  9. static char *rcsid = "$Header: /f/src2/encore.bin/cucca/mm/tarring-it-up/RCS/keywords.c,v 2.1 90/10/04 18:24:35 melissa Exp $";
  10. #endif
  11.  
  12. #include "mm.h"
  13. #include "parse.h"
  14. #include "message.h"
  15. #include "rd.h"
  16.  
  17. extern keylist user_keywords;
  18. char *safe_strcpy();
  19.  
  20. keylist
  21. free_keylist(kl)
  22. keylist kl;
  23. {
  24.     keylist fk;
  25.  
  26.     if (kl) {
  27.     for(fk = kl; *fk != nil; fk++)
  28.         free(*fk);
  29.     free(kl);
  30.     kl = nil;
  31.     }
  32.     return(nil);
  33. }
  34.  
  35. keylist
  36. add_keyword(str,kl) 
  37. char *str;
  38. keylist kl;
  39. {
  40.     int count;
  41.     char *key_validate();
  42.     char *cp;
  43.     if (!lookup_keyword(str,kl)) {
  44.     cp = key_validate(str);
  45.     if (cp == NULL || *cp == NULL)
  46.         return(kl);
  47.     for(count = 0; kl && kl[count]; count++);
  48.     kl = (keylist) safe_realloc(kl,
  49.                    (2+count)*sizeof(char *));
  50.     kl[count++] = safe_strcpy(cp);
  51.     kl[count] = nil;
  52.     }
  53.     return(kl);
  54. }
  55.  
  56. keylist
  57. rem_keyword(str, kl)
  58. char *str;
  59. keylist kl;
  60. {
  61.     keylist fk;
  62.     
  63.     if (strcmp(str,"*") == 0 && kl) {
  64.     free(kl);
  65.     return(nil);
  66.     }
  67.     for(fk = kl; fk && *fk != nil; fk++)
  68.     if (ustrcmp(*fk, str) == 0)
  69.         break;
  70.     if (fk && *fk) {
  71.     free(*fk);
  72.     do {
  73.         *fk = *(fk+1);
  74.         fk++;
  75.     } while (*fk);
  76.  
  77.     if (kl[0] == nil) {
  78.         free(kl);
  79.         return(nil);
  80.     }
  81.     }
  82.     return(kl);
  83. }
  84.  
  85. lookup_keyword(str, kl)
  86. char *str;
  87. keylist kl;
  88. {
  89.     keylist fk;
  90.     
  91.     if (strcmp(str,"*") == 0 && kl)
  92.     return(true);
  93.     for(fk = kl; fk && *fk != nil; fk++)
  94.     if (ustrcmp(*fk, str) == 0)
  95.         return(true);
  96.     return(false);
  97. }
  98.  
  99. keytab *
  100. mk_keyword_keytab(k1, k2)
  101. keylist k1,k2;
  102. {
  103.     keylist k,keys=nil;
  104.     int l1,l2;
  105.     keytab *keylist_to_keytab();
  106.  
  107.     for(k = k1; k && *k; k++)
  108.     keys = add_keyword(*k,keys);
  109.     for(k = k2; k && *k; k++)
  110.     keys = add_keyword(*k,keys);
  111.     if (keys != nil)
  112.     sort_keys(keys);
  113.     return(keylist_to_keytab(keys));
  114. }
  115.  
  116. keycmp(a,b)
  117. char **a,**b;
  118. {
  119.     return(strcmp(*a,*b));
  120. }
  121.  
  122. sort_keys(kl)
  123. keylist kl;
  124. {
  125.     int i;
  126.     keylist k;
  127.  
  128.     if (kl == nil)
  129.     return;
  130.     for(i = 0, k = kl; *k; k++, i++);
  131.     return(qsort(kl, i, sizeof(char *), keycmp));
  132. }
  133.  
  134.  
  135. keytab *
  136. keylist_to_keytab(kl)
  137. keylist kl;
  138. {
  139.     keylist k;
  140.     static keywrd *keys = nil;
  141.     static keytab tab;
  142.     int i,len;
  143.  
  144.     for(len = 0, k = kl; k && *k; k++, len++);
  145.     if (keys != nil) {
  146.     free(keys);
  147.     }
  148.     if (len > 0)
  149.     keys = (keywrd *)malloc(len * sizeof(keywrd));
  150.     else keys = nil;
  151.     for(i = 0; i < len; i++) {
  152.     keys[i]._kwkwd = kl[i];
  153.     keys[i]._kwflg = 0;
  154.     keys[i]._kwval = i;
  155.     }
  156.     tab._ktcnt = len;
  157.     tab._ktwds = keys;
  158.     return(&tab);
  159. }
  160.  
  161.  
  162. static brktab keybrk = {
  163.     {
  164.     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x3f,
  165.     0x80, 0x00, 0x00, 0x1e, 0x80, 0x00, 0x00, 0x1f,
  166.     },
  167.     {
  168.     0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0x00, 0x3f,
  169.     0x80, 0x00, 0x00, 0x1e, 0x80, 0x00, 0x00, 0x1f,
  170.     },
  171. };
  172.  
  173. static brktab fldbrk = {
  174.     {
  175.     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x3f,
  176.     0x80, 0x00, 0x00, 0x1e, 0x80, 0x00, 0x00, 0x1f,
  177.     },
  178.     {
  179.     0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0x00, 0x3f,
  180.     0x80, 0x00, 0x00, 0x1e, 0x80, 0x00, 0x00, 0x1f,
  181.     },
  182. };
  183.  
  184. char *
  185. parse_keywords(kt)
  186. keytab *kt;
  187. {
  188.     static fdb keys = { _CMKEY, 0, nil, nil, nil, nil, &keybrk };
  189.     static fdb astfdb = { _CMTOK, CM_SDH, nil, (pdat) "*" };
  190.     keys._cmdat = (pdat) kt;
  191.     parse(fdbchn(&astfdb,&keys,nil), &pv, &used);
  192.     if (used == &keys)
  193.     return(kt->_ktwds[pv._pvkey]._kwkwd);
  194.     else
  195.     return("*");
  196. }
  197.  
  198. char *
  199. parse_new_keywords()
  200. {
  201.     keytab *kt = mk_keyword_keytab(cf?cf->keywords:nil,user_keywords);
  202.     static fdb keys = { _CMKEY, 0, nil, nil, nil, nil, &keybrk };
  203.     static fdb fldfdb = { _CMFLD, CM_SDH, nil, nil, "New Keyword", nil,
  204.                   &fldbrk };
  205.  
  206.     keys._cmdat = (pdat) kt;
  207.     parse(fdbchn(&keys,&fldfdb,nil), &pv, &used);
  208.     if (used == &keys)
  209.     return(kt->_ktwds[pv._pvkey]._kwkwd);
  210.     else
  211.     return(atmbuf);
  212. }
  213.  
  214. char *
  215. parse_old_keywords()
  216. {
  217.     keytab *kt = mk_keyword_keytab(cf?cf->keywords:nil,nil); 
  218.  
  219.  
  220.  
  221.  
  222.     static fdb keys = { _CMKEY, 0, nil, nil, nil, nil, &keybrk };
  223.     static fdb astfdb = { _CMTOK, 0, nil, (pdat) "*" };
  224.  
  225.     keys._cmdat = (pdat) kt;
  226.     parse(fdbchn(&keys,&astfdb,nil), &pv, &used);
  227.     if (used == &keys)
  228.     return(kt->_ktwds[pv._pvkey]._kwkwd);
  229.     else
  230.     return("*");
  231. }
  232.  
  233.  
  234. cmd_keyword(n) 
  235. int n;
  236. {
  237.     if (mode & MM_SEND) {
  238.     char *key;
  239.  
  240.     noise("on outgoing message");
  241.     key = (safe_strcpy(parse_new_keywords()));
  242.     confirm();
  243.     outgoing_keyword(key);
  244.     }
  245.     else {
  246.     do_keyword();
  247.     }
  248. }
  249.  
  250. do_keyword() {
  251.     message *m;
  252.     char *key;
  253.  
  254.     if (!check_cf(O_RDWR))        /* pre-check file existence */
  255.     return;
  256.     key = (safe_strcpy(parse_new_keywords()));
  257.     if (!parse_sequence ("current",NULL,NULL)) {
  258.     if (!check_cf(O_WRONLY))    /* need write permission */
  259.         return;
  260.     m = &cf->msgs[cf->current];
  261.     m->keywords = add_keyword(key,m->keywords);
  262.     set_msg_keywords(m);
  263.     cf->keywords = add_keyword(key,cf->keywords);
  264.     m->flags |= M_MODIFIED;
  265.     (*msg_ops[cf->type].wr_msg)(cf,m,cf->current,0);
  266.     }
  267.     else {
  268.     int n;
  269.     if (!check_cf(O_WRONLY))    /* need write permission */
  270.         return;
  271.     for (n = sequence_start (cf->sequence); n;
  272.          n = sequence_next (cf->sequence)) {
  273.         m = &cf->msgs[cf->current];
  274.         m->keywords = add_keyword(key,m->keywords);
  275.         set_msg_keywords(m);
  276.         cf->keywords = add_keyword(key,cf->keywords);
  277.         m->flags |= M_MODIFIED;
  278.         (*msg_ops[cf->type].wr_msg)(cf,m,cf->current,0);
  279.     }
  280.     seq_print (true);
  281.     }
  282.     free(key);
  283. }
  284.  
  285. cmd_unkeyword(n) 
  286. int n;
  287. {
  288.     char *key;
  289.  
  290.     if (mode & MM_SEND) {
  291.     char *parse_current_keywords();
  292.     noise("from outgoing message");
  293.     key = (safe_strcpy(parse_current_keywords()));
  294.     confirm();
  295.     unoutgoing_keyword(key);
  296.     }
  297.     else {
  298.     message *m;
  299.     if (!check_cf(O_RDWR))        /* going to try and modify things */
  300.         return;
  301.     key = (safe_strcpy(parse_old_keywords()));
  302.     if (!parse_sequence ("current",NULL,NULL)) {
  303.         if (!check_cf(O_WRONLY))    /* need write permission */
  304.         return;
  305.         m = &cf->msgs[cf->current];
  306.         m->keywords = rem_keyword(key,m->keywords);
  307.         set_msg_keywords(m);
  308.         m->flags |= M_MODIFIED;
  309.         (*msg_ops[cf->type].wr_msg)(cf,m,cf->current,0);
  310.     }
  311.     else {
  312.         int n;
  313.         if (!check_cf(O_WRONLY))    /* need write permission */
  314.         return;
  315.         for (n = sequence_start (cf->sequence); n;
  316.          n = sequence_next (cf->sequence)) {
  317.         m = &cf->msgs[cf->current];
  318.         m->keywords = rem_keyword(key,m->keywords);
  319.         set_msg_keywords(m);
  320.         m->flags |= M_MODIFIED;
  321.         (*msg_ops[cf->type].wr_msg)(cf,m,cf->current,0);
  322.         }
  323.         seq_print (true);
  324.     }
  325.     }
  326.     free(key);
  327. }
  328.  
  329. set_msg_keywords(m)
  330. message *m;
  331. {
  332.     char *hfind();
  333.     char *begin = m->text;
  334.     char *oldkey = hfind("keywords",begin);
  335.     char *newkey=nil;
  336.     char *end=nil;
  337.     keylist k;
  338.     int len=0;
  339.     char *newmsg, *skipheader();
  340.  
  341.     if (oldkey) 
  342.     end = skipheader(oldkey);    /* point to next header */
  343.     else {                /* make it the last header */
  344.     if (m->keywords == nil)
  345.         return;
  346.     oldkey = search("\n\n",m->text);
  347.     if (oldkey == nil)
  348.         oldkey = end = begin;
  349.     else
  350.         end = ++oldkey;        /* move past one '\n' */
  351.     }
  352.  
  353.     if (m->keywords) {            /* create the new keywords: field */
  354.  
  355.     for(k = m->keywords; *k; k++)
  356.         len += strlen(*k) + ((*(k+1)) ? 2 : 0); /* new keyword + ", " */
  357.  
  358.     newkey = malloc(len + 2 + strlen("Keywords: "));
  359.  
  360.     strcpy(newkey,"Keywords: ");
  361.     for(k = m->keywords; *k; k++) {
  362.         strcat(newkey,*k);
  363.         if (*(k+1))
  364.         strcat(newkey,", ");
  365.     }
  366.     strcat(newkey,"\n");
  367.     }
  368.     len = (oldkey - begin);
  369.     if (newkey) len += strlen(newkey);
  370.     if (end) len += strlen(end);
  371.     newmsg = malloc(len+1);
  372.     strncpy(newmsg,begin,oldkey-begin);
  373.     newmsg[oldkey-begin] = '\0';
  374.     if (newkey) {
  375.     strcat(newmsg,newkey);
  376.     free(newkey);
  377.     }
  378.     if (end)
  379.     strcat(newmsg,end);
  380.     free(m->text);
  381.     m->text = newmsg;
  382.     m->size = len;
  383. }
  384.  
  385. char *
  386. parse_current_keywords()
  387. {
  388.     keytab *kt;
  389.     static fdb keys = { _CMKEY };
  390.     static fdb astfdb = { _CMTOK, 0, nil, (pdat) "*" };
  391.     extern mail_msg *current;
  392.     int flag;
  393.  
  394.     flag = (current->keywords && current->keywords->keys);
  395.     kt = mk_keyword_keytab(flag ? current->keywords->keys : nil ,nil);
  396.     keys._cmdat = (pdat) kt;
  397.     parse(fdbchn(&keys,&astfdb,nil), &pv, &used);
  398.     if (used == &keys)
  399.     return(kt->_ktwds[pv._pvkey]._kwkwd);
  400.     else
  401.     return("*");
  402. }
  403.  
  404. get_incoming_keywords(cf,m)
  405. msgvec *cf;
  406. message *m;
  407. {
  408.     char *htext();
  409.     char *k = htext("keywords", m->text);
  410.     char *c1, *c2, *stripspaces();
  411.  
  412.     c2 = k;
  413.     if (k == nil)
  414.     return;
  415.     k = stripspaces(k);
  416.     while((c1 = index(k,',')) != nil) {
  417.     *c1 = '\0';
  418.     while(*k == ' ') k++;
  419.     m->keywords = add_keyword(k,m->keywords);
  420.     if (cf)                /* sendmail only wants message done */
  421.         cf->keywords = add_keyword(k,cf->keywords);
  422.     *c1 = ',';
  423.     k = c1 + 1;
  424.     }
  425.     while(*k == ' ') k++;
  426.     if (*k) {
  427.     m->keywords = add_keyword(k,m->keywords);
  428.     if (cf)
  429.         cf->keywords = add_keyword(k,cf->keywords);
  430.     }    
  431.     free(c2);
  432. }
  433.  
  434. keylist 
  435. match_keylist(s)
  436. char *s;
  437. {
  438.     char *c1, *c2, *stripspaces();
  439.     keylist kl=nil;
  440.  
  441.     s = stripspaces(s);
  442.     while((c1 = index(s,',')) != nil) {
  443.     *c1 = '\0';
  444.     while(*s == ' ') s++;
  445.     kl = add_keyword(s,kl);
  446.     *c1 = ',';
  447.     s = c1 + 1;
  448.     }
  449.     while(*s == ' ') s++;
  450.     if (*s) {
  451.     kl = add_keyword(s, kl);
  452.     }    
  453.     return(kl);
  454. }
  455.  
  456. char *
  457. key_validate(str) 
  458. char *str;
  459. {
  460.     static char buf[100];
  461.     int i,j;
  462.     
  463.     strcpy(buf,str);
  464.     for(i = strlen(buf) - 1; i>= 0; i--)
  465.     if (isspace(buf[i])) 
  466.         buf[i] = '\0';
  467.     else
  468.         break;
  469.     
  470.     for(i = 0; i < strlen(buf); i++)
  471.     if (!isspace(buf[i])) 
  472.         break;
  473.     if (i > 0)
  474.     bcopy(&buf[i], buf, strlen(&buf[i])+1);
  475.     for(i = 0; i < strlen(buf); i++) {
  476.     if (isspace(buf[i])){
  477.         buf[i] = '_';
  478.     }
  479.     else if (!isprint(buf[i])) {
  480.         buf[i] = 'X';
  481.     }
  482.     }
  483.     return(buf);
  484. }
  485.     
  486.  
  487.  
  488. /*
  489.  * keylist_copy:
  490.  * take a keylist and malloc up a copy
  491.  */
  492.  
  493. keylist
  494. keylist_copy (kl)
  495. keylist kl;
  496. {
  497.     int i = 0;
  498.     keylist nk, k;
  499.  
  500.     for (k = kl; *k != nil; k++)
  501.     i++;
  502.     nk = (keylist) malloc ((i+1)*sizeof (char *));
  503.     for (i = 0; kl[i] != nil; i++)
  504.     nk[i] = safe_strcpy (kl[i]);
  505.     nk[i] = nil;
  506.     return (nk);
  507. }
  508.     
  509.